package com.wxzl.community.common.base

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.gson.JsonSyntaxException
import com.wxzl.community.common.http.ApiException
import com.wxzl.community.common.http.DataNullException
import com.wxzl.community.common.utils.ext.log
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import rxhttp.wrapper.exception.HttpStatusCodeException
import java.net.ConnectException
import java.net.SocketTimeoutException

typealias Block<T> = suspend () -> T
typealias Error = suspend (e: Exception) -> Unit
typealias Cancel = suspend (e: Exception) -> Unit
typealias Empty = suspend () -> Unit

/**
 * Created by xiaojianjun on 2019-09-20.
 */
open class ViewModelBase : ViewModel() {


    //异常数据
    val exception: MutableLiveData<Exception> = MutableLiveData()


    //异常数据
    val token_exception: MutableLiveData<Boolean> = MutableLiveData()

    //http请求进度数据
    val showProgress = MutableLiveData<Boolean>()

    //http请求成功状态数据
    val submitResult = MutableLiveData<Boolean>()

    //网络异常
    val network_err = MutableLiveData<Boolean>()

    //接口返回code!= 200
    val api_err = MutableLiveData<String>()

    val nulldata_err = MutableLiveData<String>()

    val msg= MutableLiveData<String>()

    //服务器response.code=500等
    val service_err= MutableLiveData<String>()

    val err4033=  MutableLiveData<HttpStatusCodeException>()

    /**
     * 创建并执行协程
     * @param block 协程中执行
     * @param error 错误时执行
     * @return Job
     */
    protected fun launch(block: Block<Unit>, error: Error? = null, empty: Empty? = null, cancel: Cancel? = null): Job {
        return viewModelScope.launch {
            try {
                block.invoke()
                showProgress.postValue(false)
            } catch (e: Exception) {
                showProgress.postValue(false)
                when (e) {
                    is CancellationException -> {
                        cancel?.invoke(e)
                    }
                    is DataNullException-> {
                        if (empty != null){
                            empty.invoke()
                        }else{
                            onError(e)
                            error?.invoke(e)
                        }
                    }
                    else -> {
                        e.log()
                        //通用的错误处理代码
                        onError(e)
                        //扏行自己定义的错误处理代码
                        error?.invoke(e)
                    }
                }
            }
        }
    }




    /**
     * 统一处理错误
     * @param e 异常
     */
    private fun onError(e: Throwable) {
        when (e) {
            is ApiException -> {
                if (e.code == 403) {
                    token_exception.value =true
                }
                else {
                    api_err.value = e.msg

                }


            }
            is HttpStatusCodeException ->{

                if (e.statusCode=="403"){
                    err4033.value = e
                }else{
                    service_err.value = e.message
                }


            }

            is DataNullException -> {

                nulldata_err.value = e.msg

            }

            is ConnectException -> {
                // 连接失败

                network_err.value = true
            }
            is java.net.UnknownHostException -> {

                network_err.value = true

            }
            is SocketTimeoutException -> {
                // 请求超时
                network_err.value = true

            }
            is JsonSyntaxException -> {
                // 数据解析错误 ,一般在调试时打印
                api_err.value = "数据格式错误"
            }
            else -> {
                // 其他错误


            }
        }



    }


}
